// ==========================================================================
// gin-sns自动生成控制器相关代码，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:54 +0800 CST
// path: app/controller/module/post_api.go
// author：jon
// ==========================================================================
package module

import (
	"gin-sns/app/controller/api/cache"
	"gin-sns/app/controller/api/render"
	"gin-sns/app/ginframe/response"
	"gin-sns/app/ginframe/tools"
	"gin-sns/app/ginframe/utils/gconv"
	"gin-sns/app/model"
	"gin-sns/app/model/constants"
	postModel "gin-sns/app/model/module/post"
	"gin-sns/app/service/module"
	"math/rand"
	"strings"

	"github.com/gin-gonic/gin"
	//"gin-sns/app/ginframe/utils/gconv"
)

var PostApi = newPostApi()

func newPostApi() *postApi {
	return &postApi{}
}

type postApi struct {
}

//列表分页数据
func (c *postApi) ListAjax(ctx *gin.Context) {
	req := new(postModel.SelectPageReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).Log("post管理", req).WriteJsonExit()
		return
	}
	rows := make([]postModel.Entity, 0)
	result, page, err := module.PostService.SelectListByPage(req)

	if err == nil && len(result) > 0 {
		rows = result
	}

	response.BuildTable(ctx, page.Total, rows).WriteJsonExit()
}

//新增页面保存
func (c *postApi) AddSave(ctx *gin.Context) {
	req := new(postModel.AddReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Add).SetMsg(err.Error()).Log("帖子新增数据", req).WriteJsonExit()
		return
	}

	id, err := module.PostService.AddSave(req, ctx)

	if err != nil || id <= 0 {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Add).Log("帖子新增数据", req).WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetData(id).Log("帖子新增数据", req).WriteJsonExit()
}

//修改页面保存
func (c *postApi) EditSave(ctx *gin.Context) {
	req := new(postModel.EditReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Edit).SetMsg(err.Error()).Log("帖子修改数据", req).WriteJsonExit()
		return
	}

	rs, err := module.PostService.EditSave(req, ctx)

	if err != nil || rs <= 0 {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Edit).Log("帖子修改数据", req).WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetBtype(model.Buniss_Edit).Log("帖子修改数据", req).WriteJsonExit()
}

//删除数据
func (c *postApi) Remove(ctx *gin.Context) {
	req := new(model.RemoveReq)
	//获取参数
	if err := ctx.ShouldBind(req); err != nil {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Del).SetMsg(err.Error()).Log("帖子删除数据", req).WriteJsonExit()
		return
	}

	rs := module.PostService.DeleteRecordByIds(req.Ids)

	if rs > 0 {
		response.SucessResp(ctx).SetBtype(model.Buniss_Del).Log("帖子删除数据", req).WriteJsonExit()
	} else {
		response.ErrorResp(ctx).SetBtype(model.Buniss_Del).Log("帖子删除数据", req).WriteJsonExit()
	}
}

// 同步帖子相关计数
/*
func (c *postApi) GetSynccount(ctx *gin.Context) {
	go func() {
		module.PostService.Scan(func(posts []postModel.Entity) bool {
			for _, post := range posts {
				CountComment := commentService.Count(model.EntityTypePost, post.Id)
				countLike := module.LikeService.Count(post.Id)
				_ = module.PostService.Updates(post.Id, map[string]interface{}{
					"comment_count": CountComment,
					"like_count":    countLike,
				})
			}
			return true
		})
	}()
	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}
*/

// 发表帖子
func (c *postApi) PostCreate(ctx *gin.Context) {
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}
	title := strings.TrimSpace(ctx.GetString("title"))
	content := strings.TrimSpace(ctx.GetString("content"))

	tags := strings.Split(ctx.GetString("tags"), ",") //todo
	summary := tools.GetSummary(content, 256)

	post, err := module.PostService.Publish(user.Id, title, summary, content,
		constants.ContentTypeMarkdown, 0, tags, "", false)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetData(render.BuildSimplePost(post)).WriteJsonExit()
	return
}

// 编辑时获取详情
func (c *postApi) GetEditBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	post, _ := module.PostService.SelectRecordById(postId)
	if post == nil || post.Status != model.PostStatusOk {
		response.ErrorResp(ctx).SetMsg("话题不存在或已被删除").WriteJsonExit()
		return
	}
	if post.UserId != user.Id {
		response.ErrorResp(ctx).SetMsg("无权限").WriteJsonExit()
		return
	}

	tags := module.PostService.GetPostTags(postId)
	var tagNames []string
	if len(tags) > 0 {
		for _, tag := range tags {
			tagNames = append(tagNames, tag.Title)
		}
	}

	response.SucessResp(ctx).SetData(gin.H{
		"postId":  post.Id,
		"title":   post.Title,
		"content": post.Content,
		"tags":    strings.Join(tagNames, ","), //todo
	}).WriteJsonExit()

}

// 编辑帖子
func (c *postApi) PostEditBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	post, _ := module.PostService.SelectRecordById(postId)
	if post == nil || post.Status != model.PostStatusOk {
		response.ErrorResp(ctx).SetMsg("话题不存在或已被删除").WriteJsonExit()
		return
	}
	if post.UserId != user.Id {
		response.ErrorResp(ctx).SetMsg("无权限").WriteJsonExit()
		return
	}

	title := strings.TrimSpace(ctx.GetString("title"))
	content := strings.TrimSpace(ctx.GetString("content"))
	tags := strings.Split(ctx.GetString("tags"), ",")

	err := module.PostService.Edit(postId, tags, title, content)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetData(render.BuildSimplePost(post)).WriteJsonExit()
	return
}

// 删除帖子
func (c *postApi) PostDeleteBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}
	post, _ := module.PostService.SelectRecordById(postId)
	if post == nil || post.Status != model.PostStatusOk {
		response.SucessResp(ctx).SetMsg("not found").WriteJsonExit()
		return
	}
	if post.UserId != user.Id {
		response.SucessResp(ctx).SetMsg("无权限").WriteJsonExit()
		return
	}
	ok := module.PostService.DeleteRecordById(postId)
	if !ok {
		response.ErrorResp(ctx).SetMsg("delete failed").WriteJsonExit()
		return
	}
	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

// 帖子详情
func (c *postApi) GetBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	post, _ := module.PostService.SelectRecordById(postId)
	if post == nil || post.Status != model.PostStatusOk {
		response.ErrorResp(ctx).SetMsg("帖子不存在").WriteJsonExit()
		return
	}
	module.PostService.IncrViewCount(postId) // 增加浏览量
	response.SucessResp(ctx).SetData(render.BuildPost(post)).WriteJsonExit()
	return
}

// 点赞
func (c *postApi) PostLikeBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}
	err := module.LikeService.Like(user.Id, postId)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
	}
	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

func (c *postApi) GetRecentlikesBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	users := module.LikeService.GetRecentUsers(constants.EntityTypePost, postId, 5)

	response.SucessResp(ctx).SetData(users).WriteJsonExit()
	return
}

// 最新帖子
func (c *postApi) GetRecent(ctx *gin.Context) {
	posts := module.PostService.GetNewestPosts(10) //limit:10

	response.SucessResp(ctx).SetData(render.BuildSimplePosts(posts)).WriteJsonExit()
	return
}

// 用户最近的帖子
func (c *postApi) GetUserRecent(ctx *gin.Context) {
	userId := ctx.GetInt64("userId")

	posts := module.PostService.GetUserNewestPosts(userId)

	response.SucessResp(ctx).SetData(render.BuildSimplePosts(posts)).WriteJsonExit()
	return
}

// 用户帖子列表
func (c *postApi) GetUserPosts(ctx *gin.Context) {
	userId := gconv.Int64(ctx.Param("userId"))

	pageNum := ctx.GetInt("page")

	req := new(postModel.SelectPageReq)

	req.PageNum = pageNum
	req.UserId = userId
	req.Status = model.PostStatusOk

	rows := make([]postModel.Entity, 0)
	result, page, err := module.PostService.SelectListByPage(req)

	if err == nil && len(result) > 0 {
		rows = result
	}

	response.BuildTable(ctx, page.Total, rows).WriteJsonExit()

}

// 帖子列表
func (c *postApi) GetPosts(ctx *gin.Context) {
	userId := gconv.Int64(ctx.Param("userId"))

	pageNum := ctx.GetInt("page")

	req := new(postModel.SelectPageReq)

	req.PageNum = pageNum
	req.UserId = userId
	req.Status = model.PostStatusOk

	rows := make([]postModel.Entity, 0)
	result, page, err := module.PostService.SelectListByPage(req)

	if err == nil && len(result) > 0 {
		rows = result
	}

	response.BuildTable(ctx, page.Total, rows).WriteJsonExit() //BuildSimplePosts
	return
}

// 标签帖子列表
func (c *postApi) GetTagPosts(ctx *gin.Context) {
	page := ctx.GetInt64("page") // 1
	tagId := ctx.GetInt64("tagId")

	posts, _ := module.PostService.GetTagPosts(tagId, page)
	//return tools.JsonPageData(render.BuildSimplePosts(posts), paging)
	response.SucessResp(ctx).SetData(render.BuildSimplePosts(posts)).WriteJsonExit()
	return
}

// 收藏
func PostFavoriteBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}
	err := module.FavoriteService.AddPostFavorite(user.Id, postId)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
	}
	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

// 推荐
func (c *postApi) GetRecommend(ctx *gin.Context) {
	posts := cache.PostCache.GetRecommendPosts()
	if posts == nil || len(posts) == 0 {
		response.SucessResp(ctx).SetData(true).WriteJsonExit()
		return
	} else {
		dest := make([]postModel.Entity, len(posts))
		perm := rand.Perm(len(posts))
		for i, v := range perm {
			dest[v] = posts[i]
		}
		end := 10
		if end > len(posts) {
			end = len(posts)
		}
		ret := dest[0:end]
		response.SucessResp(ctx).SetData(render.BuildSimplePosts(ret)).WriteJsonExit()
		return
	}
}

// // 采集发布
// func (c *postApi) PostBotPublish(ctx *gin.Context) {
// 	token := ctx.FormValue("token")
// 	data, err := ioutil.ReadFile("./data/publish_token")
// 	if err != nil {
// 		return tools.JsonErrorMsg("ReadToken error: " + err.Error())
// 	}
// 	token2 := strings.TrimSpace(string(data))
// 	if token != token2 {
// 		return tools.JsonErrorMsg("Token invalidate")
// 	}
// 	userId := tools.FormValueInt64Default(ctx, "userId", 0)
// 	title := strings.TrimSpace(ctx.GetString("title"))
// 	content := strings.TrimSpace(ctx.GetString("content"))
// 	tags := tools.FormValueStringArray(ctx, "tags")
// 	extraDataStr := ctx.GetString("extraData")
// 	extraData := gjson.Parse(extraDataStr).Map()
// 	if userId <= 0 {
// 		return tools.JsonErrorMsg("用户编号不能为空")
// 	}
// 	post, err2 := module.PostService.Publish(userId, tags, title, content, extraData)
// 	if err2 != nil {
// 		return tools.JsonError(err2)
// 	}
// 	return tools.NewEmptyRspBuilder().Put("id", post.Id).JsonResult()
// }

// 收藏
func (c *postApi) PostCommentBy(ctx *gin.Context) {
	postId := ctx.GetInt64("postId")
	user := module.UsertokenService.GetCurrent(ctx)
	if user == nil {
		response.ErrorResp(ctx).SetMsg(tools.ErrorNotLogin.Error()).WriteJsonExit()
		return
	}

	err := module.FavoriteService.AddPostFavorite(user.Id, postId)
	if err != nil {
		response.ErrorResp(ctx).SetMsg(err.Error()).WriteJsonExit()
	}
	response.SucessResp(ctx).SetData(true).WriteJsonExit()
	return
}

// 分类文章列表
func (c *postApi) GetCategoryPosts(ctx *gin.Context) {
	cursor := ctx.GetInt64("cursor")
	categoryId := ctx.GetInt64("categoryId")

	posts, cursor := module.PostService.GetCategoryPosts(categoryId, cursor)
	response.SucessResp(ctx).SetData(render.BuildSimplePosts(posts)).WriteJsonExit()
	return
}
